home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Sound Cards
/
Programming Sound Cards.iso
/
sound_56
/
mixing.asm
< prev
next >
Wrap
Assembly Source File
|
1995-01-01
|
16KB
|
426 lines
model large,pascal
noeffect EQU dw offset no_effect
.DATA
INCLUDE GENERAL.DEF
EXTRN tickbuffer :DWORD
EXTRN post8bit :WORD
EXTRN curtick :BYTE
EXTRN curspeed :BYTE
EXTRN curline :BYTE
EXTRN BPT :WORD
EXTRN EndOfSong :BYTE
EXTRN usedchannels:BYTE
EXTRN volumetableptr :DWORD
EXTRN CHANNEL :TChannel
EXTRN Userate :WORD
EXTRN gvolume :BYTE
EXTRN patterndelay :BYTE
EXTRN smpEMShandle :WORD
EXTRN frameseg :WORD
EXTRN DMArealBufsize :WORD
EXTRN TickBytesLeft :WORD
nextPosition DW ?
sample2calc DW ? ; in mono number of bytes/ in stereo number of words
curchannel DB ?
calleffects DB ?
effects noeffect
noeffect
noeffect
noeffect
dw offset VolumeEfcts ; effect 'D'
dw offset Pitchdowns ; effect 'E'
dw offset Pitchups ; effect 'F'
dw offset Portamento ; effect 'G'
dw offset Vibrato ; effect 'H'
dw offset Tremor ; effect 'I'
dw offset Arpeggio ; effect 'J'
dw offset Vib_Vol ; effect 'K'
dw offset Port_Vol ; effect 'L'
noeffect
noeffect
noeffect
noeffect
dw offset Retrigg ; effect 'Q'
dw offset Tremolo ; effect 'R'
dw offset Specialsets ; effect 'S' ; <- for notecut/delay reasons
noeffect
dw offset fineVibrato ; effect 'U'
noeffect
vol_cmd2nd dw offset volslidedown
dw offset volslideup
noeffect
noeffect
pitdwn_cmd2nd dw offset pitchdown
noeffect
noeffect
pitup_cmd2nd dw offset pitchup
noeffect
noeffect
retrig_cmd2nd noeffect
dw offset slddown
dw offset use2div3
dw offset use1div2
dw offset sldup
dw offset use3div2
dw offset use2times
; and for all special commands :
special_cmd2nd noeffect ; S0? - nothin
noeffect ; set filter
noeffect ; set glissando
noeffect ; set finetune
noeffect ; set vibrato waveform
noeffect ; set tremolo waveform
noeffect ; does not exist
noeffect ; does not exist
noeffect ; maybe later (it's E8x - panning )
noeffect ; does not exist
noeffect ; stereo control
noeffect ; Pattern loop things
dw offset Notecut
dw offset Notedelay
noeffect ; Pattern delay
noeffect ; funkrepeat
dwofs macro name, no
dw offset &name&no
endm
; stereo innerloop table:
zaehler = 0
st_innerloop_tbl LABEL WORD
rept 32
dwofs st_inner, %zaehler
zaehler = zaehler + 1
endm
; mono innerloop table:
zaehler = 0
mn_innerloop_tbl LABEL WORD
rept 32
dwofs mn_inner, %zaehler
zaehler = zaehler + 1
endm
ENDS
.CODE
.386
PUBLIC calc_stereo_tick
PUBLIC calc_mono_tick
EXTRN readnewnotes
EXTRN SetupNewInst
EXTRN SetNewNote
CalcFrequStep MACRO
; IN: ax = period
; OUT: destroys EDX,EBX
and eax,0ffffh ; clear upper 16bit
xor edx,edx
mov dx,[Userate]
mul edx ; EAX = Userate*Period
mov ebx,eax
xor edx,edx
mov dx,0dah
mov eax,77900000h ; EDX:EAX = 1712*8363*10000h
div ebx
; 1712 * 8363 * 10000h
; EAX = ----------------------
; Userate * Period
ENDM
INCLUDE BORDER.INC
INCLUDE STEREO.INC
INCLUDE MONO.INC
; for stereo and mono the same :
no_effect: retn ; <- sorry for this :(
VolumeEfcts: ; effect 'D'
mov bx,ds:[channel.cmd2nd+bp]
jmp [vol_cmd2nd+bx]
volslidedown: mov al,ds:[channel.Parameter+bp]
and al,0fh
sub ds:[channel.SampleVol+bp],al
jnc vlsdwn
mov ds:[channel.SampleVol+bp],0
vlsdwn: retn
volslideup: mov al,ds:[channel.Parameter+bp]
shr al,4
add ds:[channel.SampleVol+bp],al
cmp ds:[channel.SampleVol+bp],64
jb vlsup
mov ds:[channel.SampleVol+bp],63
vlsup: mov al,ds:[channel.SampleVol+bp]
mul [gvolume]
shr ax,6
mov ds:[channel.SampleVol+bp],al
retn
Pitchdowns: ; effect 'E'
mov bx,ds:[channel.cmd2nd+bp]
jmp [pitdwn_cmd2nd+bx]
Pitchdown: ; we pitch down, but increase period ! (so check upper_border)
mov ax,ds:[channel.sPeriod+bp]
mov bl,ds:[channel.Parameter+bp]
xor bh,bh
shl bx,2
add ax,bx
cmp ax,ds:[channel.upper_border+bp]
jb calcnewSF
mov ax,ds:[channel.upper_border+bp]
calcnewSF: ; now calc new frequency step for this period
mov ds:[channel.sPeriod+bp],ax
cmp ax,0
je donotcalc
CalcFrequStep
mov ds:[channel.sStep+bp],EAX
donotcalc: retn
Pitchups: ; effect 'F'
mov bx,ds:[channel.cmd2nd+bp]
jmp [pitup_cmd2nd+bx]
Pitchup: ; we pitch up, but decrease period ! (so check lower_border)
mov ax,ds:[channel.sPeriod+bp]
mov bl,ds:[channel.Parameter+bp]
xor bh,bh
shl bx,2
sub ax,bx
cmp ax,ds:[channel.lower_border+bp]
ja calcnewSF
mov ax,ds:[channel.lower_border+bp]
jmp calcnewSF
Portamento: ; effect 'G'
mov bl,ds:[channel.PortPara+bp]
xor bh,bh
shl bx,2 ; <- use amiga slide = para*4
mov ax,ds:[channel.sPeriod+bp]
cmp ax,ds:[channel.wantedPeri+bp]
jg porta_down
add ax,bx
cmp ax,ds:[channel.wantedPeri+bp]
jle calcnewSF
mov ax,ds:[channel.wantedPeri+bp]
jmp calcnewSF
porta_down: sub ax,bx
cmp ax,ds:[channel.wantedPeri+bp]
jge calcnewSF
mov ax,ds:[channel.wantedPeri+bp]
jmp calcnewSF
Vibrato: ; effect 'H'
cmp ds:[channel.enabled+bp],0
je novib
; next position in table:
mov al,ds:[channel.VibPara+bp]
mov dl,al
and dl,0fh
shr al,4
mov bl,ds:[channel.Tablepos+bp]
add bl,al
cmp bl,64
jb endoftest
sub bl,64
endoftest:
mov ds:[channel.Tablepos+bp],bl
xor bh,bh
add bx,ds:[channel.VibTabOfs+bp]
mov al,ds:[bx]
imul dl
sar ax,4
mov bx,ds:[channel.Oldperiod+bp]
add ax,bx
jmp calcnewSF
novib: retn
Tremor: ; effect 'I'
retn
Arpeggio: ; effect 'J'
mov bl,ds:[ArpegPos+bp]
xor bh,bh
inc bx
cmp bx,3
jb inside ; Oh I love this song - INSIDE.S3M ;)
xor bx,bx
inside: mov ds:[ArpegPos+bp],bl
shl bx,2
; cool way to address Step 0,1,2 :
add bp,bx
mov eax,ds:[channel.step0+bp] ; <- don't think we load here _everytime_ step0 !
sub bp,bx
; now use it :
mov ds:[channel.sStep+bp],eax
retn
Vib_Vol: ; effect 'K'
; first do volslides :
call near ptr VolumeEfcts ; oh well I love ASM
; -> JUMP ARROUND, JUMP JUMP JUMP
; and now vibrato:
jmp vibrato ; that's nice ;) no need for more :)
Port_Vol: ; effect 'L'
; first do volslides :
call near ptr VolumeEfcts
; and portamento
jmp portamento
retn
retrigg: ; effect 'Q'
; do retrigg counter ...
cmp ds:[channel.ctick+bp],0
jz doretrigg
dec ds:[channel.ctick+bp]
jz doretrigg
retn
doretrigg: mov ds:[channel.sCurPos+bp],0
mov al,ds:[channel.Parameter+bp]
and al,0fh
jnz dovolchanges
retn
dovolchanges: ; do volume change :
mov ds:[channel.ctick+bp],al
mov bx,ds:[channel.cmd2nd+bp]
jmp [retrig_cmd2nd+bx]
slddown: mov cl,ds:[channel.parameter+bp]
shr cl,4
mov al,1
shl al,cl
sub ds:[channel.SampleVol+bp],al
jnc slddwnok
mov ds:[channel.SampleVol+bp],0
slddwnok: retn
use2div3: ; (it's 5/8 in real life ;)
mov al,ds:[channel.SampleVol+bp]
mov ah,al
shl al,2 ; al = 4*volume , ah = volume
add al,ah ; al = 5*volume
shr al,3 ; al = 5*volume/8
mov ds:[channel.SampleVol+bp],al
retn
use1div2: shr ds:[channel.SampleVol+bp],1
retn
sldup: mov cl,ds:[channel.parameter+bp]
shr cl,4
mov al,1
shl al,cl
add al,ds:[channel.SampleVol+bp]
voltest: cmp al,64
jb sldupok
mov al,63
sldupok: mov ds:[channel.SampleVol+bp],al
retn
use3div2: mov al,ds:[channel.SampleVol+bp]
mov ah,al
add al,al ; al = 2*volume , ah = volume
add al,ah ; al = 3*volume
shr al,1 ; al = 3*volume/2
jmp voltest
use2times: mov al,ds:[channel.SampleVol+bp]
shl al,1
jmp voltest
Tremolo: ; effect 'R'
; next position in table:
mov al,ds:[channel.Parameter+bp]
mov dl,al
and dl,0fh
shr al,4
mov bl,ds:[channel.Tablepos+bp]
add bl,al
cmp bl,64
jb endoftest2
sub bl,64
endoftest2:
mov ds:[channel.Tablepos+bp],bl
xor bh,bh
add bx,ds:[channel.TrmTabOfs+bp]
mov al,ds:[bx]
imul dl
sar ax,6
mov bl,ds:[channel.oldvolume+bp]
xor bh,bh
add bx,ax
cmp bx,63
jng ok1
mov bl,63
ok1: cmp bx,0
jnl ok2
mov bl,0
ok2: mov ds:[channel.SampleVol+bp],bl
retn
Specialsets: ; effect 'S'
mov bx,ds:[channel.cmd2nd+bp]
jmp [special_cmd2nd+bx]
retn
Notecut: dec ds:[channel.ndTick+bp]
jz docut
retn
docut: mov ds:[channel.enabled+bp],0 ;disable it ...
retn
Notedelay: dec ds:[channel.ndTick+bp]
jz StartNewNote
retn
StartNewNote: ; Ok now we have to calc things for the new note/instr ...
; 1. Setup Instrument
push fs ; segment to volumetable, but we destroy it here ...
mov si,bp
mov al,[channel.savInst+si]
cmp al,00
je nonewinst
mov [channel.InstrNo+si],al
call near ptr SetupNewInst
nonewinst: mov al,[channel.savNote+si]
cmp al,0ffh
je no_newnote
cmp al,0feh
jne normal_note
mov [channel.enabled+si],0 ; stop mixing
jmp no_newnote
normal_note: mov [channel.enabled+si],1 ; yo do mixing
mov [channel.Note+si],al
call near ptr SetNewNote
no_newnote: mov al,[channel.savVol+si]
cmp al,0ffh
je no_vol
mul [gvolume]
shr ax,6
mov [channel.SampleVol+si],al
no_vol: pop fs
mov ds:[channel.command+si],0 ; <- no more Notedelay
retn
fineVibrato: ; effect 'U'
cmp ds:[channel.enabled+bp],0
je novib
; next position in table:
mov al,ds:[channel.VibPara+bp]
mov dl,al
and dl,0fh
shr al,4
mov bl,ds:[channel.Tablepos+bp]
add bl,al
cmp bl,64
jb f_endoftest
sub bl,64
f_endoftest:
mov ds:[channel.Tablepos+bp],bl
xor bh,bh
add bx,ds:[channel.VibTabOfs+bp]
mov al,ds:[bx]
imul dl
sar ax,8
mov bx,ds:[channel.Oldperiod+bp]
add ax,bx
jmp calcnewSF
ENDS
END